package two.chapter_1.c1_3;

import java.util.ConcurrentModificationException;
import java.util.Iterator;

public class LinkStack<Item> extends Stack<Item> {

    private Node head;

    private int mod;//标记修改次数
    public LinkStack() {

    }

    public LinkStack(Stack<Item> s) {

        Stack<Item> temp = new LinkStack<>();
        for (Item item : s) {
            temp.push(item);
        }
        for (Item item : temp) {
            push(item);
        }


    }

    @Override
    public void push(Item item) {

        Node node = new Node(item);
        node.next = head;
        head = node;

        size++;
        mod++;
    }

    @Override
    public Item pop() {
        Item item = head.item;
        head = head.next;
        size--;
        mod++;
        return item;
    }

    @Override
    public Item peek() {
        return head.item;
    }

    @Override
    public Iterator<Item> iterator() {
        return new Iter();
    }

    public static Stack<String> copy(Stack<String> other) {
        Iterator<String> iterator = other.iterator();
        Stack<String> tempStack = new LinkStack<>();
        Stack<String> resultStack = new LinkStack<>();
        while (iterator.hasNext()) {
            String item = iterator.next();
            tempStack.push(item);
        }
        for (String item : tempStack) {
            resultStack.push(item);
        }
        return resultStack;
    }

    private class Node {
        Item item;
        Node next;

        public Node(Item item) {
            this.item = item;
        }
    }

    private class Iter implements Iterator<Item> {
        private Node next = head;
        private int m=mod;

        @Override
        public boolean hasNext() {
            if (m!=mod){
                throw new ConcurrentModificationException();
            }
            return next != null;
        }

        @Override
        public Item next() {
            if (m!=mod){
                throw new ConcurrentModificationException();
            }
            Item item = next.item;
            next = next.next;
            return item;
        }

        @Override
        public void remove() {

        }
    }
}
